const { ServiceError, ValidationError, UnauthorizedError, ForbiddenError, NotFoundError } = require('../utils/response');

/**
 * 全局错误处理中间件
 * @param {Error} err - 错误对象
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 * @param {Function} next - Next middleware function
 */
const errorHandler = (err, req, res, next) => {
  console.error('Error:', {
    message: err.message,
    stack: err.stack,
    url: req.url,
    method: req.method,
    ip: req.ip,
    userAgent: req.get('User-Agent')
  });

  // 自定义错误类处理
  if (err instanceof ServiceError) {
    return res.status(err.code).json(err.toResponseJSON());
  }

  // 默认错误响应
  let statusCode = 500;
  let message = '服务器内部错误';

  // 根据错误类型设置响应
  if (err.name === 'ValidationError') {
    statusCode = 400;
    message = '数据验证失败';
  } else if (err.name === 'UnauthorizedError') {
    statusCode = 401;
    message = '未授权访问';
  } else if (err.name === 'CastError') {
    statusCode = 400;
    message = '无效的数据格式';
  } else if (err.name === 'SequelizeValidationError') {
    statusCode = 400;
    message = '数据验证失败';
  } else if (err.name === 'SequelizeUniqueConstraintError') {
    statusCode = 409;
    message = '数据已存在';
  } else if (err.name === 'SequelizeForeignKeyConstraintError') {
    statusCode = 400;
    message = '外键约束错误';
  } else if (err.name === 'TokenExpiredError') {
    statusCode = 401;
    message = 'Token已过期';
  } else if (err.name === 'JsonWebTokenError') {
    statusCode = 401;
    message = '无效的Token';
  } else if (err.code === 11000) {
    statusCode = 409;
    message = '数据已存在';
  } else if (err.message) {
    message = err.message;
  }

  res.status(statusCode).json({
    code: statusCode,
    message: message,
    data: null,
    timestamp: Date.now()
  });
};

/**
 * 404错误处理中间件
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const notFoundHandler = (req, res) => {
  res.status(404).json({
    code: 404,
    message: `请求的资源不存在: ${req.method} ${req.url}`,
    data: null,
    timestamp: Date.now()
  });
};

/**
 * 异步错误捕获包装器
 * @param {Function} fn - 异步函数
 * @returns {Function} 包装后的函数
 */
const asyncHandler = (fn) => {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

/**
 * 请求日志中间件
 */
const requestLogger = (req, res, next) => {
  const start = Date.now();
  
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`${req.method} ${req.url} - ${res.statusCode} - ${duration}ms`);
  });
  
  next();
};

module.exports = {
  errorHandler,
  notFoundHandler,
  asyncHandler,
  requestLogger
};
